Conversation
📝 WalkthroughWalkthrough개발자용 주문 상태 변경 API를 구현했습니다. DeliveryRepository와 PaymentRepository에 deleteByOrder_Id 메서드를 추가하고, Order에 updateStatus 메서드를 추가한 후, DevController와 DevService에서 주문 상태를 직접 변경할 수 있는 엔드포인트와 로직을 구현했습니다. Changes
Sequence DiagramsequenceDiagram
participant Client
participant DevController
participant DevService
participant OrderRepository
participant PaymentRepository
participant DeliveryRepository
Client->>DevController: PATCH /dev/orders/{orderId}/status<br/>(orderId, targetStatus)
DevController->>DevService: resetOrderStatus(orderId, targetStatus)
alt targetStatus = PAYMENT_PENDING
DevService->>PaymentRepository: deleteByOrder_Id(orderId)
PaymentRepository-->>DevService: Deletion complete
else targetStatus = DELIVERY_IN_PROGRESS or<br/>DELIVERY_COMPLETED
DevService->>DeliveryRepository: deleteByOrder_Id(orderId)
DeliveryRepository-->>DevService: Deletion complete
end
DevService->>OrderRepository: Update order status
OrderRepository-->>DevService: Status updated
DevService-->>DevController: void
DevController-->>Client: HTTP 200<br/>ApiResponse<Void>
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@src/main/java/org/sopt/poti/global/dev/DevService.java`:
- Around line 58-77: The current resetOrderStatus method uses bulk deletes
(paymentRepository.deleteByOrder_Id and deliveryRepository.deleteByOrder_Id)
which bypass JPA cascade/orphanRemoval on Order; change to remove child entities
via the aggregate root or let JPA cascade handle it: load the Order entity
(order already fetched), obtain its payments/deliveries collections, clear or
remove those child entities (e.g.,
order.getPayments().clear()/order.getDeliveries().clear() or iterate and remove
each child entity) and then save/update the Order so JPA executes cascading
deletes, or alternatively delete each child entity by repository.delete(entity)
after loading them to preserve entity lifecycle rules; ensure this logic is
applied inside resetOrderStatus and respects existing cascade = CascadeType.ALL,
orphanRemoval = true on the Order entity.
🧹 Nitpick comments (1)
src/main/java/org/sopt/poti/domain/order/entity/Order.java (1)
154-156: 상태 전이 검증 우회 리스크.
이 메서드는 전이 규칙을 모두 건너뛰므로 프로덕션 코드에서 실수로 호출되면 도메인 규칙이 깨질 수 있어요. Dev 전용임을 더 강하게 드러내도록 네이밍/주석 보강 또는 접근 범위 제한을 권장합니다.
| // 주문 상태 강제 변경 (테스트용) | ||
| @Transactional | ||
| public void resetOrderStatus(Long orderId, OrderStatus targetStatus) { | ||
| Order order = orderRepository.findById(orderId) | ||
| .orElseThrow(() -> new BusinessException(ErrorStatus.ORDER_NOT_FOUND)); | ||
|
|
||
| // 목표 상태에 따라 연관 데이터 정리 | ||
| if (targetStatus == OrderStatus.WAIT_PAY) { | ||
| // WAIT_PAY로 초기화 시, 입금 정보와 운송장 정보 모두 삭제 | ||
| paymentRepository.deleteByOrder_Id(orderId); | ||
| deliveryRepository.deleteByOrder_Id(orderId); | ||
| } else if (targetStatus == OrderStatus.WAIT_PAY_CHECK || targetStatus == OrderStatus.PAID) { | ||
| // WAIT_PAY_CHECK 또는 PAID로 초기화 시, 운송장 정보만 삭제 (입금 정보는 유지) | ||
| deliveryRepository.deleteByOrder_Id(orderId); | ||
| } | ||
| // SHIPPED, DELIVERED 등 그 이상 상태로 변경 시에는 삭제할 것이 없음 | ||
|
|
||
| // 주문 상태 변경 적용 | ||
| order.updateStatus(targetStatus); | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
git ls-files src/main/java/org/sopt/poti/ | head -30Repository: team-poti/POTI-SERVER
Length of output: 2283
🏁 Script executed:
find src/main/java/org/sopt/poti -name "DevService.java" -o -name "*Repository.java" | grep -E "(Payment|Delivery|Order)" | head -20Repository: team-poti/POTI-SERVER
Length of output: 455
🏁 Script executed:
cat -n src/main/java/org/sopt/poti/global/dev/DevService.java | sed -n '50,85p'Repository: team-poti/POTI-SERVER
Length of output: 1243
🏁 Script executed:
find src/main/java/org/sopt/poti -type f -name "*.java" | xargs grep -l "deleteByOrder_Id" | head -10Repository: team-poti/POTI-SERVER
Length of output: 275
🏁 Script executed:
find src/main/java/org/sopt/poti -type f -name "*Repository.java" | xargs grep -l "deleteByOrder" | head -10Repository: team-poti/POTI-SERVER
Length of output: 220
🏁 Script executed:
cat -n src/main/java/org/sopt/poti/domain/payment/repository/PaymentRepository.javaRepository: team-poti/POTI-SERVER
Length of output: 465
🏁 Script executed:
cat -n src/main/java/org/sopt/poti/domain/delivery/repository/DeliveryRepository.javaRepository: team-poti/POTI-SERVER
Length of output: 761
🏁 Script executed:
find src/main/java/org/sopt/poti -type f -name "Order.java"Repository: team-poti/POTI-SERVER
Length of output: 123
🏁 Script executed:
find src/main/java/org/sopt/poti -type f -name "Payment.java"Repository: team-poti/POTI-SERVER
Length of output: 127
🏁 Script executed:
find src/main/java/org/sopt/poti -type f -name "Delivery.java"Repository: team-poti/POTI-SERVER
Length of output: 129
🏁 Script executed:
cat -n src/main/java/org/sopt/poti/domain/order/entity/Order.javaRepository: team-poti/POTI-SERVER
Length of output: 5839
🏁 Script executed:
cat -n src/main/java/org/sopt/poti/domain/payment/entity/Payment.javaRepository: team-poti/POTI-SERVER
Length of output: 2547
🏁 Script executed:
cat -n src/main/java/org/sopt/poti/domain/delivery/entity/Delivery.javaRepository: team-poti/POTI-SERVER
Length of output: 1789
벌크 삭제 후 접근하지 않아 현재는 문제 없지만, 설계상 개선이 필요해.
deleteByOrder_Id는 벌크 삭제라 cascade/orphanRemoval을 무시하는데, Order가 cascade = CascadeType.ALL, orphanRemoval = true로 설정되어 있어. 지금은 삭제 후 payment/delivery를 접근하지 않아서 런타임 에러가 안 나지만, 나중에 코드가 수정되면 문제가 생길 수 있으니 cascade delete를 활용하거나 엔티티를 직접 로드해서 삭제하는 게 낫겠어.
🤖 Prompt for AI Agents
In `@src/main/java/org/sopt/poti/global/dev/DevService.java` around lines 58 - 77,
The current resetOrderStatus method uses bulk deletes
(paymentRepository.deleteByOrder_Id and deliveryRepository.deleteByOrder_Id)
which bypass JPA cascade/orphanRemoval on Order; change to remove child entities
via the aggregate root or let JPA cascade handle it: load the Order entity
(order already fetched), obtain its payments/deliveries collections, clear or
remove those child entities (e.g.,
order.getPayments().clear()/order.getDeliveries().clear() or iterate and remove
each child entity) and then save/update the Order so JPA executes cascading
deletes, or alternatively delete each child entity by repository.delete(entity)
after loading them to preserve entity lifecycle rules; ensure this logic is
applied inside resetOrderStatus and respects existing cascade = CascadeType.ALL,
orphanRemoval = true on the Order entity.
There was a problem hiding this comment.
@PBEM22 죄송합니다. 말투가 불편하셨다니 앞으로 존댓말로 말씀드리겠습니다.
기술적인 내용에 대해서는 여전히 명확하게 리뷰하되, 좀 더 정중한 어조로 진행하겠습니다.
/)_/)
(•_• )
/>💭 (앞으로 조심하겠습니다)
✏️ Learnings added
Learnt from: PBEM22
Repo: team-poti/POTI-SERVER PR: 191
File: src/main/java/org/sopt/poti/global/dev/DevService.java:58-77
Timestamp: 2026-01-23T08:12:13.661Z
Learning: PBEM22 사용자는 반말 대신 존댓말(formal Korean speech)을 선호합니다. team-poti/POTI-SERVER 저장소에서 리뷰할 때 반드시 존댓말을 사용해야 합니다.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
📌 관련 이슈
✨ 변경 사항
📸 테스트 증명 (필수)
📚 리뷰어 참고 사항
✅ 체크리스트
Summary by CodeRabbit
Release Notes
New Features
Chores
✏️ Tip: You can customize this high-level summary in your review settings.